﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Runtime.InteropServices;
using System.Net;
using System.IO;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Drawing.Drawing2D;
using System.Threading;
using Sunny.UI;
using System.Threading.Tasks;
using CoreShop.Library;
using RestSharp;
using CoreShop.Model;
using CoreShop.Services;
using CoreShop.App.Units.Interface;
using Loading;

namespace CoreShop.App
{
    public partial class frmSetupCzlAi : UIForm
    {
        public static string url = "http://127.0.0.1:17339";

        public static Hashtable config = null;
        public static ArrayList ImagePoints =  new ArrayList();
        public static int ImageWidth = 640;
        public static int ImageHeight = 480;

        private int line_width = 10;//划线的宽度设置为10
        private Color fill_color = Color.Black;//绘图区域的背景颜色
        private SolidBrush fill_brush = new SolidBrush(Color.Black);
        private Pen line_color = new Pen(new SolidBrush(Color.Black));
        private SolidBrush eraser_brush = new SolidBrush(Color.Transparent);//橡皮擦颜色
        OpaqueCommand cmd = new OpaqueCommand();
        private Graphics draw_paint, merge_paint;//中间画板
        private Image tmp_bitmap;//用来保存绘图痕迹

        List<Point> polyPoints = null;//存储绘制多边形的点集
        Rectangle rectA;//存储要用于绘图的矩形
        Image bg_image;//背景图片
        Point start;  //起始点
        Point end;   //结束点
        bool need_draw_tmp;   //在MouseMove事件中判断是否绘制矩形框

        string action_type = "";//绘图动作类型
        bool is_first_down = true;//判断是否第一次按下鼠标
        bool press_move_flag = false;

        public frmSetupCzlAi()
        {
            InitializeComponent();
        }

        private void Czl_SetStart()
        {
            string content = "";
            try
            {
                //int ret = start_service("c:\\", "Unknown");
                //int ret = start_service(Application.StartupPath, "Unknown");
                // 连接AI
                var request = WebRequest.Create(url + "/config");
                request.Method = "GET";
                var response = (HttpWebResponse)request.GetResponse();

                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }
                var status = JObject.Parse(content);
                this.Invoke(new Action(() =>
                {
                    this.label6.Text = "已连接";
                }));                
            }
            catch (Exception ex)
            {
                UIMessageTip.Show(ex.Message + " content:" + content);
            }
        }

        /// <summary>
        /// 检查激活状态
        /// </summary>
        private void Czl_GetRegister()
        {
            try
            {
                var request = WebRequest.Create(url + "/register");
                request.Method = "GET";
                var response = (HttpWebResponse)request.GetResponse();

                string content;
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }

                var status = JObject.Parse(content);

                if (status.GetValue("deviceId").Type == JTokenType.String)
                {
                    this.Invoke(new Action(() =>
                    {
                        this.lbl_RegisterState.Text = "已激活";
                        this.btnOK.Enabled = false;
                    }));
                }
                else
                {
                    this.Invoke(new Action(() =>
                    {
                        this.lbl_RegisterState.Text = "激活失败";
                        this.btnOK.Enabled = true;
                    }));
                }
            }
            catch
            {

            }
        }

        private async void PostAiInfo(string AiCode)
        {
            try
            {
                if (string.IsNullOrEmpty(AiCode)) return;
                var resultModel = await SystemApiUtil.GetActivateCodeList(AppConstVars.sysUser, AiCode);
                string result = resultModel.MessageOrString;
                AiCodeGetInfoListModel CurrentAiInfo = new AiCodeGetInfoListModel();
                GetAiCodeInfoListModel AiListInfo = result.JsonToEntity<GetAiCodeInfoListModel>();
                if (AiListInfo != null && AiListInfo.rows != null && AiListInfo.rows.Count > 0)
                {
                    CurrentAiInfo = AiListInfo.rows.Find(p => p.aiCode == AiCode);
                }
                if (CurrentAiInfo != null && !string.IsNullOrEmpty(CurrentAiInfo.aiId))
                {
                    ReturnModel returnModel = await SystemApiUtil.PostAddActivateCode(AppConstVars.sysUser, AppConstVars.sysStore,CurrentAiInfo);
                    if (returnModel.Status != ReturnStatus.Success)
                    {
                        //$"新增Ai激活码失败{CurrentAiInfo.aiCode},{returnModel.MessageOrString}".ShowError();
                        ShowInfoTip($"新增Ai激活码失败{CurrentAiInfo.aiCode},{returnModel.MessageOrString}");
                        return;
                    }

                    GetAiCodeInfoListModel gsData =
                        returnModel.MessageOrString.JsonToEntity<GetAiCodeInfoListModel>();

                    if (gsData.code != 200)
                    {
                        ShowInfoTip($"新增Ai激活码失败{CurrentAiInfo.aiCode},{returnModel.MessageOrString}");
                    }
                    else
                    {
                        ShowInfoTip($"新增Ai激活码成功{CurrentAiInfo.aiCode}，已上传云端！");
                    }
                }
            }
            catch (Exception ex)
            {
                ShowInfoTip($"新增Ai激活码失败{AiCode}！");
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void SavePara()
        {
            try
            {
                string sCode = passphraseInput.Text;
                if (sCode.IsNullOrEmpty())
                {
                    UIMessageBox.Show("选择激动码，不能保存。");
                    return;
                }
                var paraPartialModel = new ParaPartialModel();
                paraPartialModel.activateCode = passphraseInput.Text;
                AppConstVars.systemsetup.paraPartial = JsonConvert.SerializeObject(paraPartialModel);
                new corecmssystemsetupService().InsertOrUpdate(AppConstVars.systemsetup);
            }
            catch
            {
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                cmd.ShowOpaqueLayer(pnl_Form, 125, true);
                bool isRegister = false;
                if (checkValue())
                {
                    var request = WebRequest.Create(url + "/register");
                    request.ContentType = "application/json";
                    request.Method = "POST";
                    var payload = new JObject();
                    payload["passphrase"] = this.passphraseInput.Text;

                    using (Stream requestStream = request.GetRequestStream())
                    {
                        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(payload.ToString());
                        requestStream.Write(buffer, 0, buffer.Length);
                    }
                    var response = (HttpWebResponse)request.GetResponse();

                    string content;
                    using (var sr = new StreamReader(response.GetResponseStream()))
                    {
                        content = sr.ReadToEnd();
                    }

                    var status = JObject.Parse(content);

                    if (status.GetValue("deviceId").Type == JTokenType.Null)
                    {
                        this.lbl_RegisterState.Text = "激活失败";
                        return;
                    }
                    isRegister = true;
                }

                if (isRegister) 
                {
                    var request = WebRequest.Create(url + "/update-config");
                    request.Method = "POST";
                    using (Stream requestStream = request.GetRequestStream())
                    {
                        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("");
                        requestStream.Write(buffer, 0, buffer.Length);
                    }

                    var response = (HttpWebResponse)request.GetResponse();

                    string content;
                    using (var sr = new StreamReader(response.GetResponseStream()))
                    {
                        content = sr.ReadToEnd();
                    }

                    if (response.StatusCode != HttpStatusCode.NoContent)
                    {
                        this.lbl_RegisterState.Text = "激活失败";
                        return;
                    }
                }
                if (isRegister)
                {
                    var request = WebRequest.Create(url + "/update-classifier");
                    request.Method = "POST";

                    var response = (HttpWebResponse)request.GetResponse();

                    string content;
                    using (var sr = new StreamReader(response.GetResponseStream()))
                    {
                        content = sr.ReadToEnd();
                    }

                    if (response.StatusCode != HttpStatusCode.NoContent)
                    {
                        this.lbl_RegisterState.Text = "激活失败";
                        return;
                    }
                }
                this.lbl_RegisterState.Text = "已激活";                
                SavePara();
                PostAiInfo(passphraseInput.Text);
                UIMessageBox.Show("激活成功，需要重新启动前台系统", true, true);
                Environment.Exit(0);
            }
            catch(Exception ex)
            {
                UIMessageTip.Show(ex.Message);
            }
            finally
            {
                cmd.HideOpaqueLayer();
            }
        }

        private void frmRegisterCzlAi_Load(object sender, EventArgs e)
        {
            action_type = "多边形";
            bg_image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            //中间画布
            tmp_bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            //创建空白画板
            draw_paint = Graphics.FromImage(tmp_bitmap);

            //ai激活码
            if (AppConstVars.systemsetup.paraPartialModel == null)
            {
                AppConstVars.systemsetup.paraPartialModel = new ParaPartialModel();
            }
            passphraseInput.Text = AppConstVars.systemsetup.paraPartialModel.activateCode;

            LoadCzlPara();
        }

        private void LoadCzlPara()
        {
            ShowWaitForm("AI设备初始化中，请稍等...");
            try
            {
                Task.Factory.StartNew(() =>
                {
                    GlobalConstVars.czlAIBusiness.StopProcess();
                    Thread.Sleep(500);
                    GlobalConstVars.czlAIBusiness.StartProcess();
                }).TaskDis();
                Thread.Sleep(5000);
                Czl_SetStart();
                Thread.Sleep(5000);
                Czl_GetRegister();
                Thread.Sleep(3000);
                Czl_GetCameraImg();
                Thread.Sleep(1000);
                Czl_GetConfig();                
            }
            catch (Exception ex) 
            {
                HideWaitForm();
                MessageBox.Show("错误：" + ex.Message);
            }
            finally
            {
                HideWaitForm();
            }
        }

        /// <summary>
        /// 发送AI指令(深圳创智链chuangzhilian)
        /// </summary>
        public void Czl_GetCameraImg()
        {
            Image result;
            String exceptionText = "";
            try
            {
                var request = WebRequest.Create(url + "/camera-images");
                request.Method = "GET";
                var response = (HttpWebResponse)request.GetResponse();
                Stream str = response.GetResponseStream();
                result = Image.FromStream(str);
                this.Invoke(new Action(() =>
                {
                    //pictureBox1.Image = result;
                    pictureBox1.BackgroundImage = result;
                    ImageWidth = result.Width;
                    ImageHeight = result.Height;
                }));
            }
            catch (Exception ex)
            {
                exceptionText = ex.ToString();
            }
        }
        
        /// <summary>
        /// 发送AI指令(深圳创智链chuangzhilian)
        /// </summary>
        public void Czl_GetConfig()
        {
            try
            {
                var request = WebRequest.Create(url + "/config");
                request.Method = "GET";
                var response = (HttpWebResponse)request.GetResponse();
                string content;
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }

                if (content.Length > 100)
                {
                    config = (Hashtable)PluSoft.Utils.JSON.Decode(content);
                    var status = JObject.Parse(content);
                    Hashtable model = config["model"] as Hashtable;
                    var activityDomainSize = CommFunc.ConvertToInt32(model["activityDomainSize"]);
                    var logarithmActivityDomain = CommFunc.ConvertToBooten(model["logarithmActivityDomain"]);
                    if ((activityDomainSize == 1) && (logarithmActivityDomain))
                    {
                        cboDomainSize.SelectedIndex = 0;
                    }
                    else if ((activityDomainSize == 25) && (!logarithmActivityDomain))
                    {
                        cboDomainSize.SelectedIndex = 2;
                    }
                    else 
                    {
                        cboDomainSize.SelectedIndex = 1;
                    }
                    this.label6.Text = "已连接";
                }
                else cboDomainSize.SelectedIndex = 1;
            }
            catch (Exception ex)
            {
                UIMessageTip.Show(ex.Message);
            }
            try {
                this.cmbSyncData.SelectedIndex = AppConstVars.systemsetup.paraPartialModel.syncData;
            }
            catch
            {
            }           

        }
               

        /// <summary>
        /// 发送AI指令(深圳创智链chuangzhilian)
        /// </summary>
        public void Czl_GetLogs()
        {
            try
            {
                var request = WebRequest.Create(url + "/logs");
                request.Method = "GET";
                var response = (HttpWebResponse)request.GetResponse();
                string content;
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }
                rtb_log.Text = content;
            }
            catch (Exception ex)
            {
                UIMessageTip.Show(ex.Message);
            }
        }   

        private bool checkValue()
        {
            string sCode = passphraseInput.Text;
            if (sCode.IsNullOrEmpty())
            {
                MessageBox.Show("AI激活码不能空。");
                return false;
            }
            return true;
        }

        private void btnSaveDomainSize_Click(object sender, EventArgs e)
        {
            if (!checkValue()) return;
            if ((config == null) || (config.Count < 3))
            {
                UIMessageTip.Show("未获取到AI参数配置，无法提交.");
            }
            Hashtable model = config["model"] as Hashtable;
            if (cboDomainSize.SelectedIndex == 0)
            {                
                model["activityDomainSize"] = 1;
                model["logarithmActivityDomain"] = true;
            }
            else if (cboDomainSize.SelectedIndex == 2)
            {
                model["activityDomainSize"] = 25;
                model["logarithmActivityDomain"] = false;
            }
            else
            {
                model["activityDomainSize"] = 10;
                model["logarithmActivityDomain"] = true;
            }

            try
            {
                var request = WebRequest.Create(url + "/config");
                request.ContentType = "application/json";
                request.Method = "POST";
                using (Stream requestStream = request.GetRequestStream())
                {
                    string mjson = JsonConvert.SerializeObject(config);
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(mjson);
                    requestStream.Write(buffer, 0, buffer.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();

                string content = response.StatusCode.ToString();
                if (content == "OK")
                {
                    SavePara();
                    UIMessageTip.Show("提交成功。");
                }
                else
                {
                    UIMessageTip.Show("保存失败：" + response);
                }               
            }
            catch (Exception ex)
            {
            }

        }

        private void SetPoints(Point point, bool isFirst)
        {
            if (isFirst)
            {
                ImagePoints = new ArrayList();
            }
            Hashtable htPoint = new Hashtable();
            decimal xPoint = 1;
            if ((point.X < ImageWidth) && (ImageWidth > 1))
            {
                decimal xTemp = CommFunc.ConvertToDecimal(point.X.ToString());
                xPoint = Math.Round(xTemp / ImageWidth, 1);
            }
            decimal yPoint = 1;
            if ((point.Y < ImageHeight) && (ImageHeight > 1))
            {
                decimal yTemp = CommFunc.ConvertToDecimal(point.Y.ToString()) ;
                yPoint = Math.Round(yTemp / ImageHeight, 1);
            }
            htPoint["x"] = xPoint;
            htPoint["y"] = yPoint;
            ImagePoints.Add(htPoint);
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            //绘制多边形  low版本
            if (is_first_down)  //首先第一次创建两个点如下(e.X, e.Y），（ e.X + 1, e.Y + 1)
            {
                //first point down
                if (e.Button == MouseButtons.Left)
                {
                    is_first_down = false;
                    if (polyPoints == null) polyPoints = new List<Point>();
                    polyPoints.Add(e.Location);
                    SetPoints(e.Location, true);
                    //Point point = new Point(e.X + 1, e.Y + 1);
                    //polyPoints.Add(point);
                    need_draw_tmp = true;
                }
            }
            else
            {
                //add new point
                if ((e.Button == MouseButtons.Left) && (polyPoints.Count < 4))
                {
                    //添加新的点
                    Point point = new Point(e.X, e.Y);
                    polyPoints.Add(point);
                    SetPoints(point, false);
                    //this.richTextBox1.AppendText(string.Format("X={0};y={1}", e.X, e.Y) + "\r\n");
                }
                if (polyPoints.Count == 4)
                {
                    //把当前的点填充到顶点集合中去  方便填充                        
                    draw_ploy(action_type.IndexOf("填充") >= 0);
                }
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            //绘制多边形
            if (need_draw_tmp)
            {
                //if (e.Button != MouseButtons.Left) return;
                end = e.Location;
                pictureBox1.Invalidate();//此代码不可省略
                //Graphics g = pictureBox1.CreateGraphics();
                //抗锯齿
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            PictureBox pic = sender as PictureBox;
            if (polyPoints != null)
            {
                if (need_draw_tmp)
                {
                    //抗锯齿
                    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                    e.Graphics.DrawLine(Pens.Yellow, polyPoints.First(), end);
                    e.Graphics.DrawLine(Pens.Red, polyPoints.Last(), end);
                    if (polyPoints.Count > 1)
                    {
                        for (int i = 0; i < polyPoints.Count - 1; i++)
                        {
                            e.Graphics.DrawLine(Pens.Yellow, polyPoints[i], polyPoints[i + 1]);
                        }
                    }
                }
            }
        }

        private void draw_ploy(bool fill = true)
        {
            //绘制矩形框 并填充
            //抗锯齿
            draw_paint.SmoothingMode = SmoothingMode.HighQuality;

            //填充多边形
            if (fill)
            {
                draw_paint.FillPolygon(fill_brush, polyPoints.ToArray());
            }
            else
            {
                draw_paint.DrawPolygon(line_color, polyPoints.ToArray());
            }
            pictureBox1.Image = get_merge_bitmap();
            is_first_down = true;
            need_draw_tmp = false;
            polyPoints = null;
        }

        private Bitmap get_merge_bitmap()
        {
            Bitmap tmp_bmp = (Bitmap)bg_image.Clone();
            merge_paint = Graphics.FromImage(tmp_bmp);
            merge_paint.DrawImage(tmp_bitmap, 0, 0);//将中间画布绘制的内容绘制到原始画布上
            merge_paint.Dispose();
            return tmp_bmp;
        }

        private void btnSaveAreaXY_Click(object sender, EventArgs e)
        {
            if (ImagePoints == null) 
            {
                MessageBox.Show("没有选择区域，不能保存。");
                return;
            }
            if (ImagePoints.Count != 4)
            {
                MessageBox.Show("选择区域无效，不能保存。");
                return;
            }
            try
            {
                Hashtable htPoints = new Hashtable();
                htPoints["points"] = ImagePoints;
                var request = WebRequest.Create(url + "/config/image-crop");
                request.ContentType = "application/json";
                request.Method = "POST";
                using (Stream requestStream = request.GetRequestStream())
                {
                    string mjson = JsonConvert.SerializeObject(htPoints);
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(mjson);
                    requestStream.Write(buffer, 0, buffer.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();

                string content = response.StatusCode.ToString();
                if ((content == "OK") || (content == "NoContent"))
                {
                    MessageBox.Show("保存成功。");
                }
                else {
                    MessageBox.Show("保存失败：" + response);
                }            
            }
            catch (Exception ex)
            {
            }
        }

        private void btn_cleare_Click(object sender, EventArgs e)
        {
            draw_paint.Clear(Color.White);

            bg_image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            //中间画布
            tmp_bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            //创建空白画板
            draw_paint = Graphics.FromImage(tmp_bitmap);

            pictureBox1.Image = null;
            pictureBox1.Invalidate();
            pictureBox1.Refresh();
            polyPoints = null;
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 2) {
                Czl_GetLogs();
            }
        }

        private void btn_GetAiPass_Click(object sender, EventArgs e)
        {
            GsGetAiCodeList productSelect = new GsGetAiCodeList((int)GlobalEnumVars.AiType.Czl);
            productSelect.TopMost = true;
            if (productSelect.ShowDialog() == DialogResult.Yes)
            {
                if (productSelect.SelectCurrentAiCodeInfo != null)
                {
                    passphraseInput.Text = productSelect.SelectCurrentAiCodeInfo.aiCode;
                    //PostAiInfo(passphraseInput.Text);
                }
            }
        }

        private void passphraseInput_TextChanged(object sender, EventArgs e)
        {
            //SettingModelUtil.settingsModel.aI.CDKEY = passphraseInput.Text;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            Task.Factory.StartNew(() =>
            {
                GlobalConstVars.czlAIBusiness.StopProcess();
                Thread.Sleep(500);
                UIMessageBox.Show("停止成功，请退出软件再打开。");
                //GlobalConstVars.czlAIBusiness.StartProcess();

            }).TaskDis();            
        }

        private void btnSyncData_Click(object sender, EventArgs e)
        {
            try
            {
                if (!checkValue()) return;
                var client = new RestClient("http://localhost:17339/config/sync-config");
                client.Timeout = -1;
                var request = new RestRequest(Method.POST);
                client.UserAgent = "Apifox/1.0.0 (https://apifox.com)"; // 切换同步模式，auto为开启自动同步学习数据
                request.AddHeader("Content-Type", "application/json");
                string mode = "grouping";
                if (cmbSyncData.SelectedIndex == 1) mode = "auto";
                var body = @"{
                " + "\n" + string.Format(@"    ""mode"":""{0}""", mode) + "\n" + @"}";
                request.AddParameter("application/json", body, ParameterType.RequestBody);
                IRestResponse response = client.Execute(request);
                string result = response.Content;
                string content = response.StatusCode.ToString();
                if (content == "NoContent")
                {
                    AppConstVars.systemsetup.paraPartialModel.syncData = this.cmbSyncData.SelectedIndex;
                    AppConstVars.systemsetup.paraPartial = JsonConvert.SerializeObject(AppConstVars.systemsetup.paraPartialModel);
                    new corecmssystemsetupService().InsertOrUpdate(AppConstVars.systemsetup);
                    SavePara();
                    UIMessageBox.Show("提交成功。");
                }
                else
                {
                    UIMessageBox.Show("保存失败：" + response);
                }             
            }
            catch(Exception ex){
                UIMessageBox.Show("错误：" + ex.Message);
            }
        }
    }
}
